package br.ufc.great.dtx.tm;

import java.util.Vector;

import br.ufc.great.dtx.server.DTXOutput;
import br.ufc.great.dtx.server.DTXServerThread;
import br.ufc.great.dtx.tm.sch.Scheduler;

/**
 * 
 * @author Leonardo Oliveira Moreira
 *
 * Classe thread que é delegada para atender uma transação
 */
public class TransactionManagerThread extends Thread {

	private TransactionManager transactionManager;
	private Transaction transaction;
	private DTXServerThread request;
	private DTXOutput output;
	
	public TransactionManagerThread(DTXOutput output, TransactionManager transactionManager, Transaction transaction, DTXServerThread request) {
		this.output = output;
		this.transactionManager = transactionManager;
		this.transaction = transaction;
		this.request = request;
		//setPriority(MAX_PRIORITY);
	}
	
	public void run() {
		long init = System.currentTimeMillis();
		output.print(getClass().getSimpleName(), "Transaction " + transaction.getId() + " iniciou", DTXOutput.TEST);
		Scheduler scheduler = transactionManager.getScheduler();
		transaction.setThread(this);
		//setPriority(MIN_PRIORITY);
		scheduler.sendTransaction(transaction);
		synchronized (this) {
			try {
				if (! transaction.isEnded())
					wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}				
		}
		long finish = System.currentTimeMillis();
		String time = "";
		if ((finish - init) < 1000) {
			time += "0." + (finish - init) % 1000;
		}
		else {
			time += ((finish - init) / 1000) + "." + (finish - init) % 1000; 
		}
		output.print(getClass().getSimpleName(), "Transaction " + transaction.getId() + " executou as operações", DTXOutput.TEST);
		if (transaction.getStatus() == Transaction.COMMITED)
			output.print(getClass().getSimpleName(), "Transaction " + transaction.getId() + " executed in " + time + " secs", DTXOutput.HIGHLIGHT);
		else
			output.print(getClass().getSimpleName(), "Transaction " + transaction.getId() + " executed in " + time + " secs", DTXOutput.ERROR);
		synchronized (transactionManager) {
			transactionManager.endTransaction(transaction, request);			
		}
	}
	
	public synchronized void end() {
		notify();
	}
	
}
